#include "platform.h"

#if defined COMPILE_FOR_LINUX
/***************************** Sleep ************************************/
/**  Provide linux replacement for windows function.
\param [in] Milliseconds the time to wait for in milliseconds.
*/
void Sleep(unsigned long MilliSeconds)
{
    usleep(MilliSeconds*1000); //convert to microseconds
}
#endif // defined COMPILE_FOR_LINUX

#if defined COMPILE_FOR_LPC21
/**  Provide linux replacement for windows function.
\note I implement that one in my private header file today...
\param [in] Milliseconds the time to wait for in milliseconds.
*/
/*static void Sleep(unsigned long MilliSeconds)
{
#   warning Sleep function not implemented
}
*/
#endif // defined COMPILE_FOR_LPC21

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
/***************************** getch ************************************/
/** Replacement for the common dos function of the same name. Reads a
single unbuffered character from the 'keyboard'.
\return The character read from the keyboard.
*/
int getch(void)
{
    char ch;

    /* Read in one character */
    read(0,&ch,1);

    return ch;
}
#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
/***************************** kbhit ************************************/
/** Replacement for the common dos function of the same name. Indicates if
there are characters to be read from the console.
\retval 0 No characters ready.
\retval 1 Characters from the console ready to be read.
*/
int kbhit(void)
{
    /* return 0 for no key pressed, 1 for key pressed */
    int return_value = 0;

    /* time struct for the select() function, to only wait a little while */
    struct timeval select_time;
    /* file descriptor variable for the select() call */
    fd_set readset;

    /* we're only interested in STDIN */
    FD_ZERO(&readset);
    FD_SET(STDIN_FILENO, &readset);

    /* how long to block for - this must be > 0.0, but could be changed
    to some other setting. 10-18msec seems to work well and only
    minimally load the system (0% CPU loading) */
    select_time.tv_sec = 0;
    select_time.tv_usec = 10;

    /* is there a keystroke there? */
    if (select(1, &readset, NULL, NULL, &select_time))
    {
        /* yes, remember it */
        return_value = 1;
    }


    /* return with what we found out */
    return return_value;
}
struct termios keyboard_origtty;
#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN


/***************************** PrepareKeyboardTtySettings ***************/
/** Set the keyboard tty to be able to check for new characters via kbhit
getting them via getch
*/

void PrepareKeyboardTtySettings(void)
{
#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
    /* store the current tty settings */
    if (!tcgetattr(0, &keyboard_origtty))
    {
        struct termios tty;
        /* start with the current settings */
        tty = keyboard_origtty;
        /* make modifications to put it in raw mode, turn off echo */
        tty.c_lflag &= ~ICANON;
        tty.c_lflag &= ~ECHO;
        tty.c_lflag &= ~ISIG;
        tty.c_cc[VMIN] = 1;
        tty.c_cc[VTIME] = 0;

        /* put the settings into effect */
        tcsetattr(0, TCSADRAIN, &tty);
    }
#endif
}


/***************************** ResetKeyboardTtySettings *****************/
/** Reset the keyboard tty to original settings
*/
void ResetKeyboardTtySettings(void)
{
#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
    /* reset the tty to its original settings */
    tcsetattr(0, TCSADRAIN, &keyboard_origtty);
#endif
}

#if !defined COMPILE_FOR_LPC21
/***************************** DebugPrintf ******************************/
/**  Prints a debug string depending the current debug level. The higher
 the debug level the more detail that will be printed.  Each print
 has an associated level, the higher the level the more detailed the
 debugging information being sent.
 \param [in] level the debug level of the print statement, if the level
 is less than or equal to the current debug level it will be printed.
 \param [in] fmt a standard printf style format string.
 \param [in] ... the usual printf parameters.
 */
#if !defined INTEGRATED_IN_WIN_APP

int debug_level = 2;

void DebugPrintf(int level, const char *fmt, ...)
{
    va_list ap;
	
    if (level <= debug_level)
    {
        char pTemp[2000];
        va_start(ap, fmt);
        //vprintf(fmt, ap);
        vsprintf(pTemp, fmt, ap);
        TRACE(pTemp);
        va_end(ap);
        fflush(stdout);
    }
}
#endif
#endif // !defined COMPILE_FOR_LPC21

/***************************** DumpString ******************************/
/**  Prints an area of memory to stdout. Converts non-printables to hex.
 \param [in] level the debug level of the block to be dumped.  If this is
 less than or equal to the current debug level than the dump will happen
 otherwise this just returns.
 \param [in] b pointer to an area of memory.
 \param [in] size the length of the memory block to print.
 \param [in] prefix string is a pointer to a prefix string.
 */
void DumpString(int level, const void *b, size_t size, const char *prefix_string)
{
    size_t i;
    const char * s = (const char*) b;
    unsigned char c;
	
    DebugPrintf(level, prefix_string);
	
    DebugPrintf(level, "'");
    for (i = 0; i < size; i++)
    {
        c = s[i];
        if (c >= 0x20 && c <= 0x7e) /*isprint?*/
        {
            DebugPrintf(level, "%c", c);
        }
        else
        {
            DebugPrintf(level, "(%02X)", c);
        }
    }
    DebugPrintf(level, "'\n");
}

